﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MindFusion.Diagramming;
using System.Data.Common;
using System.Data.SqlClient;
using System.IO;
using System.Diagnostics;

namespace Inference
{
	public partial class frmMain : Form
	{
		TaleEntities tale = null;
		public Settings settings = null;
		frmWaiting frmWait = null;
		int lastDVX = 0;
		int lastDVY = 0;
		TreeViewNode lastClickedNode = null;
		bool blockSelectSynch = false;
		public string sysDomEntities = "Имена фреймов-сущностей";
		public string sysDomSituations = "Имена фреймов-ситуаций";

		public frmMain()
		{
			InitializeComponent();
			settings = new Settings(tvMain, diagram);
			if (!settings.LoadFromFile())
				settings.LoadDefault();
			foreach (Highlighter tvh in settings.TreeViewHighlighters)
			{
				tsMain.Items.Add(tvh.CreateControlButton(new System.EventHandler(highlighterControlButton_Click)));
			}

			tsbVisibleISA.Checked = settings.LinksSettings.ShowISA;
			tsbVisibleISA.ForeColor = settings.LinksSettings.ColorISA;
			tsbVisibleNext.Checked = settings.LinksSettings.ShowNEXT;
			tsbVisibleNext.ForeColor = settings.LinksSettings.ColorNEXT;
			tsbVisibleSub.Checked = settings.LinksSettings.ShowSUB;
			tsbVisibleSub.ForeColor = settings.LinksSettings.ColorSUB;

			frmWait = new frmWaiting();
		}


		public void dvLoad()
		{
			var frames = from f in tale.Frame
						 select f;
			foreach (Frame f in frames)
			{
				TreeViewNode tvn = CreateFrameTreeViewNode(f);
				diagram.Items.Add(tvn);
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
			}
			foreach (DiagramNode dn in diagram.Nodes)
			{
				CreateLinkISA(((TreeViewNode)dn));
				CreateLinkNext(((TreeViewNode)dn));
				CreateLinkSub(((TreeViewNode)dn));
			}
		}

		void CreateLinkISA(TreeViewNode stvn)
		{
			TreeNode source = null;
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text == stvn.Caption)
				{
					source = tn;
					break;
				}
			}

			List<TreeViewNode> ltvn = settings.GetDiagramNodesFromTreeNodes(settings.GetParent(source));
			if (ltvn.Count != 0)
			{
				foreach (TreeViewNode dtvn in ltvn)
				{
					DiagramLink dl = new DiagramLink(diagram, stvn, dtvn);
					dl.Text = "is_a";
					dl.Tag = "i";
					dl.Pen = new MindFusion.Drawing.Pen(settings.LinksSettings.ColorISA, (float)0.3);
					dl.Visible = tsbVisibleISA.Checked;
					diagram.Links.Add(dl);
				}
			}
		}
		void CreateLinkNext(TreeViewNode stvn)
		{
			TreeNode source = null;
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text == stvn.Caption)
				{
					source = tn;
					break;
				}
			}

			List<TreeViewNode> ltvn = settings.GetDiagramNodesFromTreeNodes(settings.GetNext(source));
			if (ltvn.Count != 0)
			{
				foreach (TreeViewNode dtvn in ltvn)
				{
					DiagramLink dl = new DiagramLink(diagram, stvn, dtvn);
					dl.Text = "next";
					dl.Tag = "n";
					dl.Pen = new MindFusion.Drawing.Pen(settings.LinksSettings.ColorNEXT, (float)0.3);
					dl.Visible = tsbVisibleNext.Checked;
					diagram.Links.Add(dl);
				}
			}
		}
		void CreateLinkSub(TreeViewNode stvn)
		{
			TreeNode source = null;
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text == stvn.Caption)
				{
					source = tn;
					break;
				}
			}

			List<TreeViewNode> ltvn = settings.GetDiagramNodesFromTreeNodes(settings.GetSubs(source));
			if (ltvn.Count != 0)
			{
				foreach (TreeViewNode dtvn in ltvn)
				{
					DiagramLink dl = new DiagramLink(diagram, stvn, dtvn);
					dl.Text = "sub";
					dl.Tag = "s";
					dl.Pen = new MindFusion.Drawing.Pen(settings.LinksSettings.ColorSUB, (float)0.3);
					dl.Visible = tsbVisibleSub.Checked;
					diagram.Links.Add(dl);
				}
			}
		}
		public void RecreateLinks()
		{
			diagram.Links.Clear();
			foreach (DiagramNode dn in diagram.Nodes)
			{
				CreateLinkISA(((TreeViewNode)dn));
				CreateLinkNext(((TreeViewNode)dn));
				CreateLinkSub(((TreeViewNode)dn));
			}
		}

		TreeViewNode CreateFrameTreeViewNode(Frame f)
		{
			TreeViewNode tvn = new TreeViewNode();
			if (f.Name == "Ситуация")
				tvn.Tag = "X";
			else
				if (f.Name == "Сущность")
					tvn.Tag = "Z";
				else
					if (GetRoot(f.ID).ToLower() == "ситуация")
						tvn.Tag = "S";
					else
						tvn.Tag = "E";
			tvn.ConnectionStyle = TreeViewConnectionStyle.Node;
			tvn.Caption = f.Name;
			tvn.Font = new Font(FontFamily.GenericSansSerif, 10);
			tvn.Move(f.X, f.Y);
			tvn.RootItems.Add(new TreeViewItem("Слоты"));

			tvn.RootItems[0].Children.Add(new TreeViewItem("Имя фрейма: " + f.Name));

			string sISA = "";
			var isa = tale.Frame.Where(fr => fr.ID == f.Is_a);
			if (isa.Count() == 0)
				sISA = "NULL";
			else
				sISA = isa.First().Name;
			tvn.RootItems[0].Children.Add(new TreeViewItem("IS_A: " + sISA));

			var slots = from s in f.Slot
						orderby s.Number
						where s.Number != 0
						select s;
			foreach (var s in slots)
			{
				tvn.RootItems[0].Children.Add(CreateSlotTreeViewNode(s));
			}
			foreach (var tvi in tvn.RootItems[0].Children)
			{
				foreach (var item in tvi.Children)
				{
					item.Height = tvn.Font.Height;
				}
				tvi.Height = tvn.Font.Height;
			}
			tvn.Obstacle = true;
			tvn.CaptionHeight = tvn.Font.Height + 5;
			tvn.RootItems[0].Height = tvn.Font.Height;
			return tvn;
		}
		TreeViewItem CreateSlotTreeViewNode(Slot s)
		{
			TreeViewItem tvi = new TreeViewItem(s.Name);

			if (s.DomainType != null && s.DomainType != 0)
				tvi.Children.Add(new TreeViewItem("Домен: " + tale.Frame.Where(f => f.ID == s.DomainType).FirstOrDefault().Name));
			else
				tvi.Children.Add(new TreeViewItem("Домен: " + s.Domains.Name));

			var dvalues = tale.DValues.Where(dv => dv.ID == s.DefaultValue);
			string sDefaultValue = "";
			if (dvalues.Count() == 0)
				sDefaultValue = "NULL";
			else
				sDefaultValue = dvalues.First().Value;
			tvi.Children.Add(new TreeViewItem("Задание отсутствия: " + sDefaultValue));
			tvi.Children.Add(new TreeViewItem("Вопрос пользователю: " + s.Question));

			string sAllowNull = "";
			if (s.AllowNull)
				sAllowNull = "Да";
			else
				sAllowNull = "Нет";
			tvi.Children.Add(new TreeViewItem("Допустимо \"Не знаю\": " + sAllowNull));

			string sInheritance = "";
			switch (s.Inheritance)
			{
				case 1:
					sInheritance = "Override";
					break;
				case 2:
					sInheritance = "Same";
					break;
				default:
					sInheritance = "Error";
					break;
			}
			tvi.Children.Add(new TreeViewItem("Тип наследования: " + sInheritance));
			tvi.Expanded = false;
			foreach (var item in tvi.Children)
			{
				item.Height = 13;
			}
			tvi.Height = 13;
			return tvi;
		}

		private void ShowWaitingMsg(string msg)
		{
			frmWait.ShowMsg(msg);
			this.Enabled = false;
		}
		private void HideWaitingMsg()
		{
			frmWait.Close();
			this.Enabled = true;
			this.Focus();
		}

		private void beginGenerationToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string DBName = Directory.GetCurrentDirectory() + @"\Tale.mdf";
			string connect = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + DBName +
			   ";Integrated Security=True;Connect Timeout=30;User Instance=True";
			LV concl = new LV(connect);
			concl.StartConclusion();
			объяснениеToolStripMenuItem.Enabled = true;
		}


		TreeNode previousSelectedNode = null;

		public void tvLoad()
		{
			var frames = from f in tale.Frame
						 orderby f.Name
						 select f;
			foreach (var f in frames)
			{
				if (GetRoot(f.ID).ToLower() == "ситуация")
					tvMain.Nodes[0].Nodes[0].Nodes.Add(CreateFrameNode(f, false));
				else
					tvMain.Nodes[0].Nodes[1].Nodes.Add(CreateFrameNode(f, true));
			}

			RebuildDomainHierarchy();
		}

		public void RebuildDomainHierarchy()
		{
			tale = new TaleEntities();
			tvMain.Nodes[1].Nodes.Clear();

			var sortedDoms = (from d in tale.Domains
							  where d.ID != 1 && d.ID != 7
							  orderby d.DomainsValues.Count descending, d.ID
							  select d).ToList();
			//tale.Domains.Where(d => d.ID != 1 && d.ID != 7).OrderByDescending(d => d.DomainsValues.Count).ToList();

			foreach (var d in sortedDoms)
			{
				Domains par = DomainHierarchier.GetParent(d.Name, tale);
				if (par != null)
				{
					TreeNode pn = FindNode(tvMain.Nodes[1], par.Name);
					if (pn != null)
					{
						pn.Nodes.Add(CreateDomainNode(d));
					}
				}
				else
					tvMain.Nodes[1].Nodes.Add(CreateDomainNode(d));
			}

			foreach (TreeNode tn in settings.DomainNodes)
			{
				PostProcessDomainTreeNode(tn);
			}
		}

		public void PostProcessDomainTreeNode(TreeNode tn)
		{
			var subDoms = GetExpandableNodes(tn);
			var privVals = GetUnexpandableNodes(tn);
			if (subDoms.Count > 0 && privVals.Count > 0)
			{
				foreach (TreeNode pv in privVals)
				{
					foreach (TreeNode ch in subDoms)
					{
						List<string> q = GetChildNodesTexts(ch);
						if (q.Contains(pv.Text))
						{
							if (pv.Parent != null)
								pv.Parent.Nodes.Remove(pv);
						}
					}
				}
			}
		}

		public string getText(TreeNode cur)
		{
			string s = "";
			s = cur.Text;
			int i = s.IndexOf('(') - 1;
			if (i > 0)
			{
				s = s.Substring(0, i);
			}
			return s;
		}

		public List<string> GetChildNodesTexts(TreeNode cur)
		{
			List<string> res = new List<string>();

			foreach (TreeNode tn in cur.Nodes)
			{
				if (tn.Nodes.Count == 0)
					res.Add(tn.Text);
			}

			return res;
		}

		public List<TreeNode> GetExpandableNodes(TreeNode cur)
		{
			List<TreeNode> res = new List<TreeNode>();

			foreach (TreeNode tn in cur.Nodes)
			{
				if (tn.Nodes.Count > 0)
					res.Add(tn);
			}

			return res;
		}

		public List<TreeNode> GetUnexpandableNodes(TreeNode cur)
		{
			List<TreeNode> res = new List<TreeNode>();

			foreach (TreeNode tn in cur.Nodes)
			{
				if (tn.Nodes.Count == 0)
					res.Add(tn);
			}

			return res;
		}

		public TreeNode FindNode(TreeNode root, string text)
		{
			if (root.Text == text)
			{
				return root;
			}
			foreach (TreeNode item in root.Nodes)
			{
				TreeNode res = FindNode(item, text);
				if (res != null)
					return res;
			}
			return null;
		}

		TreeNode CreateFrameNode(Frame f, bool isEntity)
		{
			TreeNode tn = new TreeNode(f.Name);
			if (f.Name == "Ситуация")
				tn.Tag = "X";
			else
				if (f.Name == "Сущность")
					tn.Tag = "e";
				else
					if (isEntity)
						tn.Tag = "e";
					else
						tn.Tag = "f";
			TreeNode tmp = new TreeNode("Имя фрейма: " + f.Name);
			tmp.Tag = "q";
			tn.Nodes.Add(tmp);

			string sISA = "";
			var isa = tale.Frame.Where(fr => fr.ID == f.Is_a);
			if (isa.Count() == 0)
				sISA = "NULL";
			else
				sISA = isa.First().Name;
			tmp = new TreeNode("IS_A: " + sISA);
			tmp.Tag = "q";
			tn.Nodes.Add(tmp);

			var slots = from s in f.Slot
						orderby s.Number
						where s.Number != 0
						select s;
			foreach (var s in slots)
			{
				if(s.Name.ToLower() != "имя фрейма")
					tn.Nodes.Add(CreateSlotNode(s));
			}
			return tn;
		}

		public void deleteFrameNodes(string frameName)
		{
			tale = new TaleEntities();
			TreeViewNode tvn = getFrameTreeViewNodeByName(frameName);
			foreach (DiagramLink dl in tvn.GetAllLinks())
			{
				diagram.Links.Remove(dl);
			}
			diagram.Nodes.Remove(tvn);
			TreeNode tn = getFrameTreeNodeByName(frameName);
			tn.Parent.Nodes.Remove(tn);
		}

		public void deleteDomainNode(string domainName)
		{
			tale = new TaleEntities();
			TreeNode tn = getDomainTreeNodeByName(domainName);
			if(tn!=null)
				tn.Parent.Nodes.Remove(tn);
		}

		public void refreshFrameNodes(Frame f, string oldName)
		{
			tale = new TaleEntities();
			var ch = CheckIf.ChildrenOf(f.Name, true, tale);

			refreshOneFrameNodes(f, oldName);

			foreach (var item in ch)
			{
				refreshOneFrameNodes(item, item.Name);
			}
			RecreateLinks();
		}
		public void refreshOneFrameNodes(Frame f, string oldName)
		{
			TreeNode tn = getFrameTreeNodeByName(oldName);
			if (tn != null)
			{
				tn.Text = f.Name;
				if (f.Name == "Ситуация")
					tn.Tag = "X";
				else
					if (f.Name == "Сущность")
						tn.Tag = "e";
					else
						if (GetRoot(f.ID).ToLower() != "ситуация")
							tn.Tag = "e";
						else
							tn.Tag = "f";

				tn.Nodes.Clear();

				if (GetRoot(f.ID) == "Ситуация" && tn.Parent.Text != "Ситуации")
				{
					tvMain.Nodes[0].Nodes[1].Nodes.Remove(tn);
					tvMain.Nodes[0].Nodes[0].Nodes.Add(tn);
				}
				else
					if (GetRoot(f.ID) != "Ситуация" && tn.Parent.Text == "Ситуации")
					{
						tvMain.Nodes[0].Nodes[0].Nodes.Remove(tn);
						tvMain.Nodes[0].Nodes[1].Nodes.Add(tn);
					}

				TreeNode tmp = new TreeNode("Имя фрейма: " + f.Name);
				tmp.Tag = "q";
				tn.Nodes.Add(tmp);

				string sISA = "";
				var isa = tale.Frame.Where(fr => fr.ID == f.Is_a);
				if (isa.Count() == 0)
					sISA = "NULL";
				else
					sISA = isa.First().Name;
				tmp = new TreeNode("IS_A: " + sISA);
				tmp.Tag = "q";
				tn.Nodes.Add(tmp);

				var slots = from s in f.Slot
							orderby s.Number
							select s;
				foreach (var s in slots)
				{
                    if (s.Name.ToLower() != "имя фрейма")
					    tn.Nodes.Add(CreateSlotNode(s));
				}
			}
			TreeViewNode tvn = getFrameTreeViewNodeByName(oldName);
			if (tvn != null)
			{
				if (f.Name == "Ситуация")
					tvn.Tag = "X";
				else
					if (f.Name == "Сущность")
						tvn.Tag = "E";
					else
						if (GetRoot(f.ID).ToLower() == "ситуация")
							tvn.Tag = "S";
						else
							tvn.Tag = "E";
				tvn.ConnectionStyle = TreeViewConnectionStyle.Node;
				tvn.Caption = f.Name;
				tvn.Font = new Font(FontFamily.GenericSansSerif, 10);
				tvn.Move(f.X, f.Y);
				tvn.RootItems.Clear();
				tvn.RootItems.Add(new TreeViewItem("Слоты"));

				tvn.RootItems[0].Children.Add(new TreeViewItem("Имя фрейма: " + f.Name));

				string sISA = "";
				var isa = tale.Frame.Where(fr => fr.ID == f.Is_a);
				if (isa.Count() == 0)
					sISA = "NULL";
				else
					sISA = isa.First().Name;
				tvn.RootItems[0].Children.Add(new TreeViewItem("IS_A: " + sISA));

				var slots = from s in f.Slot
							orderby s.Number
							where s.Number != 0
							select s;
				foreach (var s in slots)
				{
					tvn.RootItems[0].Children.Add(CreateSlotTreeViewNode(s));
				}
				foreach (var tvi in tvn.RootItems[0].Children)
				{
					foreach (var item in tvi.Children)
					{
						item.Height = tvn.Font.Height;
					}
					tvi.Height = tvn.Font.Height;
				}
				tvn.Obstacle = true;


				tvn.CaptionHeight = tvn.Font.Height + 5;
				tvn.RootItems[0].Height = tvn.Font.Height;
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
			}
		}

		public void RefreshSlotNodes(Slot s, string oldName)
		{
			tale = new TaleEntities();
			var ch = CheckIf.SlotsNamedLike(s.Name, s.Frame.Name, tale);

			RefreshOneSlotNodes(s, oldName);

			foreach (var item in ch)
			{
				RefreshOneSlotNodes(item, item.Name);
			}

			RecreateLinks();
		}
		public void RefreshOneSlotNodes(Slot s, string oldName)
		{

			TreeNode tn = getSlotTreeNode(oldName, getFrameTreeNodeByName(s.Frame.Name));
			if (tn != null)
			{
				tn.Text = s.Name;
				if (s.Name.ToLower() != "next")
					tn.Tag = "s";
				else
					tn.Tag = "q";
				tn.Nodes.Clear();
				TreeNode tmp = null;
				if (s.DomainType != null && s.DomainType != 0)
					tmp = (new TreeNode("Домен: " + tale.Frame.Where(f => f.ID == s.DomainType).FirstOrDefault().Name));
				else
					tmp = new TreeNode("Домен: " + s.Domains.Name);
				tmp.Tag = "p";
				tn.Nodes.Add(tmp);

				var dvalues = tale.DValues.Where(dv => dv.ID == s.DefaultValue);
				string sDefaultValue = "";
				if (dvalues.Count() == 0)
					sDefaultValue = "NULL";
				else
					sDefaultValue = dvalues.First().Value;

				tmp = new TreeNode("Задание отсутствия: " + sDefaultValue);
				tmp.Tag = "p";
				tn.Nodes.Add(tmp);

				tmp = new TreeNode("Вопрос пользователю: " + s.Question);
				tmp.Tag = "p";
				tn.Nodes.Add(tmp);

				string sAllowNull = "";
				if (s.AllowNull)
					sAllowNull = "Да";
				else
					sAllowNull = "Нет";

				tmp = new TreeNode("Допустимо \"Не знаю\": " + sAllowNull);
				tmp.Tag = "p";
				tn.Nodes.Add(tmp);

				string sInheritance = "";
				switch (s.Inheritance)
				{
					case 1:
						sInheritance = "Override";
						break;
					case 2:
						sInheritance = "Same";
						break;
					default:
						sInheritance = "Error";
						break;
				}

				tmp = new TreeNode("Тип наследования: " + sInheritance);
				tmp.Tag = "p";
				tn.Nodes.Add(tmp);
			}
			TreeViewNode tvnf = getFrameTreeViewNodeByName(s.Frame.Name);
			if (tvnf != null)
			{
				TreeViewItem tvi = null;
				foreach (TreeViewItem t in tvnf.RootItems[0].Children)
				{
					if (t.Label == oldName)
					{
						tvi = t;
						break;
					}
				}
				if (tvi != null)
				{
					tvi.Label = s.Name;
					tvi.Children.Clear();

					if (s.DomainType != null && s.DomainType != 0)
						tvi.Children.Add(new TreeViewItem("Домен: " + tale.Frame.Where(f => f.ID == s.DomainType).FirstOrDefault().Name));
					else
						tvi.Children.Add(new TreeViewItem("Домен: " + s.Domains.Name));

					var dvalues = tale.DValues.Where(dv => dv.ID == s.DefaultValue);
					string sDefaultValue = "";
					if (dvalues.Count() == 0)
						sDefaultValue = "NULL";
					else
						sDefaultValue = dvalues.First().Value;
					tvi.Children.Add(new TreeViewItem("Задание отсутствия: " + sDefaultValue));
					tvi.Children.Add(new TreeViewItem("Вопрос пользователю: " + s.Question));

					string sAllowNull = "";
					if (s.AllowNull)
						sAllowNull = "Да";
					else
						sAllowNull = "Нет";
					tvi.Children.Add(new TreeViewItem("Допустимо \"Не знаю\": " + sAllowNull));

					string sInheritance = "";
					switch (s.Inheritance)
					{
						case 1:
							sInheritance = "Override";
							break;
						case 2:
							sInheritance = "Same";
							break;
						default:
							sInheritance = "Error";
							break;
					}
					tvi.Children.Add(new TreeViewItem("Тип наследования: " + sInheritance));
					foreach (var item in tvi.Children)
					{
						item.Height = tvnf.Font.Height;
					}
					tvi.Height = tvnf.Font.Height;
					tvi.Expanded = false;
				}
			}
		}

		TreeNode CreateSlotNode(Slot s)
		{
			tale = new TaleEntities();
			TreeNode tn = new TreeNode(s.Name);
			if (s.Name.ToLower() != "next")
				tn.Tag = "s";
			else
				tn.Tag = "q";


			TreeNode tmp = null;
			if (s.DomainType != null && s.DomainType != 0)
				tmp = (new TreeNode("Домен: " + tale.Frame.Where(f => f.ID == s.DomainType).FirstOrDefault().Name));
			else

				tmp = new TreeNode("Домен: " + s.Domains.Name);
			tmp.Tag = "p";
			tn.Nodes.Add(tmp);

			var dvalues = tale.DValues.Where(dv => dv.ID == s.DefaultValue);
			string sDefaultValue = "";
			if (dvalues.Count() == 0)
				sDefaultValue = "NULL";
			else
				sDefaultValue = dvalues.First().Value;

			tmp = new TreeNode("Задание отсутствия: " + sDefaultValue);
			tmp.Tag = "p";
			tn.Nodes.Add(tmp);

			tmp = new TreeNode("Вопрос пользователю: " + s.Question);
			tmp.Tag = "p";
			tn.Nodes.Add(tmp);

			string sAllowNull = "";
			if (s.AllowNull)
				sAllowNull = "Да";
			else
				sAllowNull = "Нет";

			tmp = new TreeNode("Допустимо \"Не знаю\": " + sAllowNull);
			tmp.Tag = "p";
			tn.Nodes.Add(tmp);

			string sInheritance = "";
			switch (s.Inheritance)
			{
				case 1:
					sInheritance = "Override";
					break;
				case 2:
					sInheritance = "Same";
					break;
				default:
					sInheritance = "Error";
					break;
			}

			tmp = new TreeNode("Тип наследования: " + sInheritance);
			tmp.Tag = "p";
			tn.Nodes.Add(tmp);

			return tn;
		}
		public void RefreshDomainNodes(Domains d, string oldName)
		{
			tale = new TaleEntities();
			TreeNode tn = getDomainTreeNodeByName(oldName);
			if (tn != null)
			{
				tn.Text = d.Name;
				tn.Tag = "d";
				tn.Nodes.Clear();
				foreach (var dv in d.DomainsValues)
				{
					TreeNode tndv = new TreeNode(dv.DValues.Value);
					tndv.Tag = "v";
					tn.Nodes.Add(tndv);
				}
			}
		}
		public TreeNode CreateDomainNode(Domains d)
		{
			tale = new TaleEntities();
			TreeNode tn = new TreeNode(d.Name);
			tn.Tag = "d";
			foreach (var dv in d.DomainsValues)
			{
				TreeNode tndv = new TreeNode(dv.DValues.Value);
				tndv.Tag = "v";
				tn.Nodes.Add(tndv);
			}
			return tn;
		}

		private void HighlightTreeView(TreeNode tn)
		{
			tn.BackColor = SystemColors.Highlight;
			tn.ForeColor = Color.White;
			foreach (Highlighter tvh in settings.TreeViewHighlighters)
			{
				if (tvh.Enabled)
					tvh.Apply(tn);
			}
			//diagramView.Refresh();
		}
		private void UnhighlightTreeView(TreeNode tn)
		{
			tn.BackColor = Color.White;
			tn.ForeColor = Color.Black;
			foreach (Highlighter tvh in settings.TreeViewHighlighters)
			{
				tvh.Clear(tn);
			}
			//diagramView.Refresh();
		}

		bool HasNoCollapsedChildren(TreeNode tn)
		{
			foreach (TreeNode t in tn.Nodes)
			{
				if (t.Nodes.Count > 0)
					if (!t.IsExpanded)
						return false;
					else
						return HasNoCollapsedChildren(t);
			}
			return true;
		}

		private void tvMain_AfterSelect(object sender, TreeViewEventArgs e)
		{
			if (previousSelectedNode != e.Node)
			{
				if (tvMain.SelectedNode != null)
				{
					btnExpand.Enabled = (!tvMain.SelectedNode.IsExpanded && tvMain.SelectedNode.Nodes.Count > 0) || !HasNoCollapsedChildren(tvMain.SelectedNode);
					btnCollapse.Enabled = tvMain.SelectedNode.IsExpanded;
				}
				previousSelectedNode = e.Node;
				HighlightTreeView(e.Node);
				if (!blockSelectSynch)
				{
					diagram.Selection.Clear();
					foreach (DiagramNode dn in diagram.Nodes)
					{
						if (((TreeViewNode)dn).Caption == e.Node.Text)
						{
							diagram.ActiveItem = dn;
							PointF p = dn.GetCenter();
							float mult = 100f / tbZoomFactor.Value;
							float newX = ((p.X - diagramView.Width * (float)0.5 * mult >= 0) ? (p.X - diagramView.Width * (float)0.5 * mult) : 0);
							float newY = ((p.Y - diagramView.Height * (float)0.5 * mult >= 0) ? (p.Y - diagramView.Height * (float)0.5 * mult) : 0);

							diagramView.ScrollTo(newX, newY);

							break;
						}
					}
				}
				else
				{
					tvMain.TopNode = e.Node;
				}
			}
		}
		private void tvMain_BeforeSelect(object sender, TreeViewCancelEventArgs e)
		{
			if (previousSelectedNode != null
				&&
				previousSelectedNode != e.Node)
			{
				UnhighlightTreeView(previousSelectedNode);
			}
		}
		private void diagram_SelectionChanged(object sender, EventArgs e)
		{
			blockSelectSynch = true;
			foreach (DiagramNode tvn in diagram.Nodes)
			{
				tvn.Pen = new MindFusion.Drawing.Pen(Color.Black, (float)0.2);
			}

			if (diagram.Selection.Nodes.Count == 1)
			{
				string selectedFrameName = ((TreeViewNode)diagram.Selection.Nodes[0]).Caption;
				foreach (TreeNode tn in settings.FrameNodes)
				{
					if (tn.Text == selectedFrameName)
					{
						tvMain.SelectedNode = tvMain.Nodes[0];
						tvMain.SelectedNode = tn;
						break;
					}
				}
			}
			else
			{
				if (diagram.Selection.Nodes.Count == 0)
				{
					if (tvMain.SelectedNode != null)
					{
						UnhighlightTreeView(tvMain.SelectedNode);
					}
				}
				else
				{
					if (tvMain.SelectedNode != null)
					{
						tvMain.SelectedNode = tvMain.Nodes[0];
					}
				}
			}
			blockSelectSynch = false;
		}
		private void tvMain_Leave(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				//UnhighlightTreeView(tvMain.SelectedNode);
			}
		}
		private void tsbVisibleNext_Click(object sender, EventArgs e)
		{
			foreach (DiagramLink dl in diagram.Links)
			{
				if (dl.Text.ToLower() == ((ToolStripButton)sender).Text.ToLower())
				{
					dl.Visible = ((ToolStripButton)sender).Checked;
				}
			}
		}
		private void tvMain_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			//TreeNode tn = e.Node;
			//if (tn != null)
			//{
			//    if (tn.PrevVisibleNode != null)
			//        tvMain.SelectedNode = tn.PrevVisibleNode;
			//    else
			//        if (tn.Parent != null)
			//            tvMain.SelectedNode = tn.Parent;
			//        else
			//            if (tn.Nodes.Count > 0)
			//            {
			//                //	tvMain.SelectedNode = tn.Nodes[0];
			//            }
			//            else
			//                tvMain.SelectedNode = tvMain.Nodes[0];

			tvMain.SelectedNode = e.Node;

			treeViewContextMenuAdjust(e.Node);
			if (e.Button == System.Windows.Forms.MouseButtons.Right)
			{
				cmsTv.Show(tvMain, e.Location);
			}

			//    //Frame ff = getFrameByName(tn.Text,new TaleEntities());
			//    //if(ff != null){
			//    //	if(GetRoot(ff.ID) == "Ситуация")
			//    //	{
			//    //		(new frmTemplateEditor(ff)).ShowDialog(); 
			//    //	}
			//    //}
			//}
		}

		#region contextMenuAdjusters
		private void treeViewContextMenuAdjust(TreeNode tn)
		{
			//tags

			//Фреймы F
			//Конкретный фрейм f , e
			//Конкретный слот s
			//Системный слот q
			//Свойство конкретного слота p
			//Сущности E
			//Ситуации S
			//Домены D
			//Конкретный домен d
			//Значение конкретного домена v
			if (tn.Tag != null)
			{
				string tag = tn.Tag.ToString();
				foreach (ToolStripItem item in cmsTv.Items)
				{
					if (item.Tag.ToString().Contains(tag))
					{

						if (item.Tag.ToString() == "d1")
						{
							item.Visible = item.Enabled = tn.Level == 1;
						}
						else
							if (item.Tag.ToString() == "d2")
							{
								item.Visible = item.Enabled = tn.Level > 1;
							}
							else
								if (item.Tag.ToString() == "v1")
								{
									item.Visible = item.Enabled = tn.Level == 2;
								}
								else
									if (item.Tag.ToString() == "v2")
									{
										item.Visible = item.Enabled = tn.Level > 2;
									}
									else
									{
										item.Visible = item.Enabled = true;
									}
					}
					else
					{
						item.Visible = item.Enabled = false;
					}
				}
			}
		}
		private void diagramViewContextMenuAdjust(TreeViewNode tvn)
		{
			//tags

			//Z = Сущность
			//X = Ситуация


			//Фреймы F
			//Конкретный фрейм f , e
			//Конкретный слот s
			//Системный слот q
			//Свойство конкретного слота p
			//Сущности E
			//Ситуации S
			//Домены D
			//Конкретный домен d
			//Значение конкретного домена v
			string tag = "n";
			if (tvn != null && tvn.Tag != null)
			{
				tag = tvn.Tag.ToString();
			}
			if (diagram.Selection.Nodes.Count > 1)
			{
				tag = "g";
			}
			if (tvn == null)
			{
				tag = "N";
			}
			foreach (ToolStripItem item in cmsDv.Items)
			{
				item.Visible = item.Enabled = item.Tag.ToString().Contains(tag);
			}
		}
		private bool diagramViewContextMenuAdjust(DiagramLink dl)
		{
			//sub s
			//next n
			string tag = "n";
			if (dl != null && dl.Text != null)
			{
				tag = dl.Text[0].ToString().ToLower();
			}
			if (diagram.Selection.Nodes.Count > 1)
			{
				tag = "g";
			}
			if (dl == null)
			{
				tag = "N";
			}
			if (tag == "i")
			{
				return false;
			}
			foreach (ToolStripItem item in cmsDv.Items)
			{
				item.Visible = item.Enabled = item.Tag.ToString().Contains(tag);
			}
			return true;

		}
		#endregion

		private void tbZoomFactor_Scroll(object sender, EventArgs e)
		{
			diagramView.ZoomFactor = tbZoomFactor.Value;
			if (tbZoomFactor.Value < 100)
			{
				lblZoom.Text = " " + tbZoomFactor.Value.ToString() + "%";
			}
			else
			{
				lblZoom.Text = tbZoomFactor.Value.ToString() + "%";
			}
		}
		private void tbZoomFactor_ValueChanged(object sender, EventArgs e)
		{
			diagramView.ZoomFactor = tbZoomFactor.Value;
			if (tbZoomFactor.Value < 100)
			{
				lblZoom.Text = " " + tbZoomFactor.Value.ToString() + "%";
			}
			else
			{
				lblZoom.Text = tbZoomFactor.Value.ToString() + "%";
			}
		}
		private void diagram_NodeModified(object sender, NodeEventArgs e)
		{
			TreeViewNode tvn = (TreeViewNode)e.Node;
			var fr = from f in tale.Frame
					 where f.Name == tvn.Caption
					 select f;
			fr.First().X = Convert.ToInt32(tvn.GetCenter().X);
			fr.First().Y = Convert.ToInt32(tvn.GetCenter().Y);
			tale.SaveChanges();
		}

		public const float zoom = 0.08f;

		public void ZoomIn(PointF p)
		{
			float mult = 100f / tbZoomFactor.Value;
			float newX = ((p.X - diagramView.Width * (float)0.5 * mult >= 0) ? (p.X - diagramView.Width * (float)0.5 * mult) : 0);
			float newY = ((p.Y - diagramView.Height * (float)0.5 * mult >= 0) ? (p.Y - diagramView.Height * (float)0.5 * mult) : 0);

			diagramView.ScrollTo(newX, newY);
			if (tbZoomFactor.Value < tbZoomFactor.Maximum)
			{
				RectangleF viewRect = diagramView.ClientToDoc(diagramView.ClientRectangle);
				viewRect.Inflate(-viewRect.Width * zoom, -viewRect.Height * zoom);
				diagramView.ZoomToRect(viewRect);
				tbZoomFactor.Value = ((int)diagramView.ZoomFactor <= tbZoomFactor.Maximum) ? (int)diagramView.ZoomFactor : tbZoomFactor.Maximum;
			}
		}
		public void ZoomOut(PointF p)
		{
			float mult = 100f / tbZoomFactor.Value;
			float newX = ((p.X - diagramView.Width * (float)0.5 * mult >= 0) ? (p.X - diagramView.Width * (float)0.5 * mult) : 0);
			float newY = ((p.Y - diagramView.Height * (float)0.5 * mult >= 0) ? (p.Y - diagramView.Height * (float)0.5 * mult) : 0);

			diagramView.ScrollTo(newX, newY);
			if (tbZoomFactor.Value > tbZoomFactor.Minimum)
			{
				RectangleF viewRect = diagramView.ClientToDoc(diagramView.ClientRectangle);
				viewRect.Inflate(viewRect.Width * zoom, viewRect.Height * zoom);
				diagramView.ZoomToRect(viewRect);
				tbZoomFactor.Value = ((int)diagramView.ZoomFactor >= tbZoomFactor.Minimum) ? (int)diagramView.ZoomFactor : tbZoomFactor.Minimum;
			}
		}

		private void diagram_NodeClicked(object sender, NodeEventArgs e)
		{
			lastDVX = (int)e.MousePosition.X;
			lastDVY = (int)e.MousePosition.Y;

			((TreeViewNode)e.Node).ResizeToFitText();
			lastClickedNode = (TreeViewNode)e.Node;

			if (tsbArrow.Checked && e.MouseButton == MouseButton.Right)
			{
				diagramViewContextMenuAdjust((TreeViewNode)e.Node);
				cmsDv.Show(diagramView.PointToScreen(diagramView.DocToClient(new Point((int)e.MousePosition.X, (int)e.MousePosition.Y))));
			}
			else
				if (tsbZoomIn.Checked)
				{
					ZoomIn(e.MousePosition);
				}
				else
					if (tsbZoomOut.Checked)
					{
						ZoomOut(e.MousePosition);
					}
		}
		private void diagram_Clicked(object sender, DiagramEventArgs e)
		{
			lastDVX = (int)e.MousePosition.X;
			lastDVY = (int)e.MousePosition.Y;

			if (tsbArrow.Checked && e.MouseButton == MouseButton.Right)
			{
				diagramViewContextMenuAdjust((TreeViewNode)null);
				cmsDv.Show(diagramView.PointToScreen(diagramView.DocToClient(new Point((int)e.MousePosition.X, (int)e.MousePosition.Y))));
			}
			if (tsbZoomIn.Checked)
			{
				ZoomIn(e.MousePosition);
			}
			else
				if (tsbZoomOut.Checked)
				{
					ZoomOut(e.MousePosition);
				}
		}
		private void diagram_LinkClicked(object sender, LinkEventArgs e)
		{
			lastDVX = (int)e.MousePosition.X;
			lastDVY = (int)e.MousePosition.Y;

			if (tsbArrow.Checked && e.MouseButton == MouseButton.Right)
			{
				//	if (diagramViewContextMenuAdjust(e.Link))
				//		cmsDv.Show(diagramView.PointToScreen(new Point((int)e.MousePosition.X, (int)e.MousePosition.Y)));
			}
			if (tsbZoomIn.Checked)
			{
				ZoomIn(e.MousePosition);
			}
			else
				if (tsbZoomOut.Checked)
				{
					ZoomOut(e.MousePosition);
				}
		}

		public void highlighterControlButton_Click(object sender, System.EventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				UnhighlightTreeView(tvMain.SelectedNode);
				HighlightTreeView(tvMain.SelectedNode);
			}
		}
		private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmPreferences f = new frmPreferences(settings);
			if (f.ShowDialog() == DialogResult.OK)
			{
				foreach (ucHighlighterSettings uchs in f.LinksSettingsControls)
				{
					uchs.UpdateHighlighter();
					switch (uchs.BoundedLink)
					{
						case LinkTypes.is_a:
							tsbVisibleISA.Checked = settings.LinksSettings.ShowISA;
							tsbVisibleISA.ForeColor = settings.LinksSettings.ColorISA;
							tsbVisibleNext_Click(tsbVisibleISA, null);
							break;
						case LinkTypes.next:
							tsbVisibleNext.Checked = settings.LinksSettings.ShowNEXT;
							tsbVisibleNext.ForeColor = settings.LinksSettings.ColorNEXT;
							tsbVisibleNext_Click(tsbVisibleNext, null);
							break;
						case LinkTypes.sub:
							tsbVisibleSub.Checked = settings.LinksSettings.ShowSUB;
							tsbVisibleSub.ForeColor = settings.LinksSettings.ColorSUB;
							tsbVisibleNext_Click(tsbVisibleSub, null);
							break;
						default:
							break;
					}
				}

				foreach (ucHighlighterSettings uchs in f.HighlighterSettingsControls)
				{
					uchs.UpdateHighlighter();
				}
				foreach (Highlighter tvh in settings.TreeViewHighlighters)
				{
					tvh.RefreshControlButton();
					highlighterControlButton_Click(tvh.ControlButton, null);
				}
			}
		}
		private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
		{
			settings.SaveToFile();
		}
		private void openToolStripMenuItem_Click(object sender, EventArgs e)
		{
			tale = new TaleEntities();
			tsMain.Enabled = true;
			tsSide.Enabled = true;
			diagramView.Enabled = true;
			tbZoomFactor.Enabled = true;
			openToolStripMenuItem.Enabled = false;
			generationToolStripMenuItem.Enabled = true;

			ShowWaitingMsg("Пожалуйста, подождите. Идет загрузка базы знаний.");
			tvLoad();
			tvMain.Nodes[0].Expand();
			dvLoad();
			HideWaitingMsg();
			tsbVisibleISA.ForeColor = tsbISA.ForeColor = settings.LinksSettings.ColorISA;
			tsbVisibleSub.ForeColor = tsbSub.ForeColor = settings.LinksSettings.ColorSUB;
			tsbVisibleNext.ForeColor = tsbNext.ForeColor = settings.LinksSettings.ColorNEXT;
		}
		private void btnExpand_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
				tvMain.SelectedNode.ExpandAll();
			tvMain.Focus();
		}
		private void btnCollapse_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
				tvMain.SelectedNode.Collapse(false);
			tvMain.Focus();
		}
		#region get'ы
		string GetRoot(int FrameID)
		{
			Frame fr;
			do
			{
				fr = tale.Frame.Where(f => f.ID == FrameID).First();
				if (fr.Is_a.HasValue)
					FrameID = fr.Is_a.Value;
				else
					FrameID = 0;
			}
			while (FrameID != 0);
			return fr.Name;
		}
		string GetRoot(string FrameName)
		{
			Frame fr = tale.Frame.Where(f => f.Name == FrameName).First();
			int FrameID = fr.ID;
			do
			{
				fr = tale.Frame.Where(f => f.ID == FrameID).First();
				if (fr.Is_a.HasValue)
					FrameID = fr.Is_a.Value;
				else
					FrameID = 0;
			}
			while (FrameID != 0);
			return fr.Name;
		}
		public int GetFrameID(TreeNode tn)
		{
			try
			{
				return tale.Frame.Where(f => f.Name == tn.Text).First().ID;
			}
			catch
			{
				return -1;
			}
		}
		public int GetFrameID(TreeViewNode tvn)
		{
			try
			{
				return tale.Frame.Where(f => f.Name == tvn.Caption).First().ID;
			}
			catch
			{
				return -1;
			}
		}
		public int GetFrameType(TreeNode tn)
		{
			if (tn.Level < 2)
				return -1;
			while (tn.Level > 2)
				tn = tn.Parent;
			return ((tn.Text == "Ситуации") ? 1 : 2);
		}
		public int GetFrameType(TreeViewNode tvn)
		{
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text == tvn.Caption)
				{
					return ((tn.Parent.Text == "Ситуации") ? 1 : 2);
				}
			}
			return -1;
		}
		public int GetSlotID(TreeNode tn)
		{
			try
			{
				return tale.Slot.Where(s => s.Name == tn.Text && s.Frame.Name == tn.Parent.Text).First().ID;
			}
			catch
			{
				return -1;
			}
		}
		#endregion



		#region contextMenuClickHandler'ы
		private void добавитьФреймToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (RunEditForms.CreateFrame(-1, 2, 50, 50) == 0)
			{
				tale = new TaleEntities();
				Frame f = tale.Frame.ToList().Last();
				tvMain.Nodes[0].Nodes[1].Nodes.Add(CreateFrameNode(f, true));
				TreeViewNode tvn = CreateFrameTreeViewNode(f);
				diagram.Items.Add(tvn);
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
				CreateLinkISA(tvn);
				CreateLinkNext(tvn);
				CreateLinkSub(tvn);

				refreshOneFrameNodes(f, f.Name);
			}

		}
		private void изменитьФреймToolStripMenuItem_Click(object sender, EventArgs e)
		{
			RunEditForms.EditFrame(GetFrameID(tvMain.SelectedNode), 2, -1, -1);
			refreshFrameNodes(getFrameByName(tvMain.SelectedNode.Text, tale), tvMain.SelectedNode.Text);
		}
		private void добавитьСитуациюToolStripMenuItem1_Click(object sender, EventArgs e)
		{
			if (RunEditForms.CreateFrame(-1, 1, 50, 50) == 0)
			{
				tale = new TaleEntities();
				Frame f = tale.Frame.ToList().Last();
				tvMain.Nodes[0].Nodes[0].Nodes.Add(CreateFrameNode(f, false));
				TreeViewNode tvn = CreateFrameTreeViewNode(f);
				diagram.Items.Add(tvn);
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
				CreateLinkISA(tvn);
				CreateLinkNext(tvn);
				CreateLinkSub(tvn);

				refreshOneFrameNodes(f, f.Name);
			}
		}
		private void изменитьСитуациюToolStripMenuItem_Click(object sender, EventArgs e)
		{
			RunEditForms.EditFrame(GetFrameID(tvMain.SelectedNode), 1, -1, -1);
			refreshFrameNodes(getFrameByName(tvMain.SelectedNode.Text, tale), tvMain.SelectedNode.Text);
		}
		private void добавитьСлотToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode.Level == 2)
			{
				if (RunEditForms.CreateSlot(GetFrameID(tvMain.SelectedNode), GetFrameType(tvMain.SelectedNode)) == 0)
				{
					refreshFrameNodes(getFrameByName(tvMain.SelectedNode.Text, tale), tvMain.SelectedNode.Text);
				}
			}
			else
				if (tvMain.SelectedNode.Level == 3)
				{
					if (RunEditForms.CreateSlot(GetFrameID(tvMain.SelectedNode.Parent), GetFrameType(tvMain.SelectedNode.Parent)) == 0)
					{
						refreshFrameNodes(getFrameByName(tvMain.SelectedNode.Parent.Text, tale), tvMain.SelectedNode.Parent.Text);
					}
				}
		}
		private void изменитьСлотToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode.Level == 3)
			{
				if (RunEditForms.EditSlot(GetSlotID(tvMain.SelectedNode), GetFrameType(tvMain.SelectedNode)) == 0)
				{
					RefreshSlotNodes(getSlotByName(tvMain.SelectedNode.Text, tvMain.SelectedNode.Parent.Text, tale), tvMain.SelectedNode.Text);
				}
			}
			else
				if (tvMain.SelectedNode.Level == 4)
				{
					if (RunEditForms.EditSlot(GetSlotID(tvMain.SelectedNode.Parent), GetFrameType(tvMain.SelectedNode.Parent)) == 0)
					{
						RefreshSlotNodes(getSlotByName(tvMain.SelectedNode.Parent.Text, tvMain.SelectedNode.Parent.Parent.Text, tale), tvMain.SelectedNode.Text);
					}
				}
		}
		private void добавитьФреймситуациюToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (RunEditForms.CreateFrame(-1, 1, lastDVX, lastDVY) == 0)
			{
				tale = new TaleEntities();
				Frame f = tale.Frame.ToList().Last();
				tvMain.Nodes[0].Nodes[0].Nodes.Add(CreateFrameNode(f, false));
				TreeViewNode tvn = CreateFrameTreeViewNode(f);
				diagram.Items.Add(tvn);
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
				CreateLinkISA(tvn);
				CreateLinkNext(tvn);
				CreateLinkSub(tvn);

				refreshOneFrameNodes(f, f.Name);
			}
		}
		private void добавитьФреймсущностьToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (RunEditForms.CreateFrame(-1, 2, lastDVX, lastDVY) == 0)
			{
				tale = new TaleEntities();
				Frame f = tale.Frame.ToList().Last();
				tvMain.Nodes[0].Nodes[1].Nodes.Add(CreateFrameNode(f, true));
				TreeViewNode tvn = CreateFrameTreeViewNode(f);
				diagram.Items.Add(tvn);
				tvn.RootItems[0].Expanded = false;
				tvn.ResizeToFitText();
				CreateLinkISA(tvn);
				CreateLinkNext(tvn);
				CreateLinkSub(tvn);

				refreshOneFrameNodes(f, f.Name);
			}
		}
		private void изменитьФреймситуациюToolStripMenuItem_Click(object sender, EventArgs e)
		{
			RunEditForms.EditFrame(GetFrameID(lastClickedNode), 1, -1, -1);
			refreshFrameNodes(getFrameByName(lastClickedNode.Caption, tale), lastClickedNode.Caption);
		}
		private void изменитьФреймсущностьToolStripMenuItem_Click(object sender, EventArgs e)
		{
			RunEditForms.EditFrame(GetFrameID(lastClickedNode), 2, -1, -1);
			refreshFrameNodes(getFrameByName(lastClickedNode.Caption, tale), lastClickedNode.Caption);
		}
		#endregion



		private void tvMain_Enter(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				//UnhighlightTreeView(tvMain.SelectedNode);
				//HighlightTreeView(tvMain.SelectedNode);
			}
		}


		public bool FrameExists(string name, TreeNode except)
		{
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text.ToLower().Trim() == name.ToLower().Trim() && tn != except)
				{
					return true;
				}
			}
			return false;
		}
		public bool DomainExists(string name, TreeNode except)
		{
			foreach (TreeNode tn in settings.DomainNodes)
			{
				if (tn.Text.ToLower().Trim() == name.ToLower().Trim() && tn != except)
				{
					return true;
				}
			}
			return false;
		}

		public bool DomainValueExists(string name, TreeNode except)
		{
			foreach (TreeNode tn in settings.FindLeaves(settings.GetTreeNodeRoot(except)))
			{
				if (tn.Text.ToLower().Trim() == name.ToLower().Trim() && tn != except)
				{
					return true;
				}
			}
			return false;
		}

		public bool SlotExists(string name, TreeNode except)
		{
			foreach (TreeNode tn in except.Parent.Nodes)
			{
				if (tn.Text.ToLower().Trim() == name.ToLower().Trim() && tn != except)
				{
					return true;
				}
			}
			if (name.ToLower().StartsWith("IS_A"))
				return true;
			if (name.ToLower().StartsWith("Имя фрейма:"))
				return true;
			return false;
		}


		public Frame getFrameByName(string name, TaleEntities tale)
		{
			var fr = tale.Frame.Where(f => f.Name == name);
			if (fr.Count() > 0)
				return fr.First();
			return null;
		}
		public Domains getDomainByName(string name, TaleEntities tale)
		{
			if (name != null)
			{
				var dom = tale.Domains.Where(d => d.Name == name);
				if (dom.Count() > 0)
					return dom.First();
			}
			return null;
		}
		public DomainsValues getDomainsValueByName(string name, string domain, TaleEntities tale)
		{
			try
			{
				var doms = from dom in tale.Domains
						   join domval in tale.DomainsValues on dom.ID equals domval.DomID
						   join dv in tale.DValues on domval.Value equals dv.ID
						   where dom.Name == domain && dv.Value == name
						   select domval;
				//var dom = tale.DValues.Where(d => (d.Value == name) && (d.DomainsValues.FirstOrDefault().Domains.Name == domain));
				if (doms.Count() > 0)
					return doms.First();
			}
			catch
			{
			}
			return null;
		}
		public DValues getDomainValueByName(string name, string domain, TaleEntities tale)
		{
			try
			{
				var doms = from dom in tale.Domains
						   join domval in tale.DomainsValues on dom.ID equals domval.DomID
						   join dv in tale.DValues on domval.Value equals dv.ID
						   where dom.Name == domain && dv.Value == name
						   select dv;
				//var dom = tale.DValues.Where(d => (d.Value == name) && (d.DomainsValues.FirstOrDefault().Domains.Name == domain));
				if (doms.Count() > 0)
					return doms.First();
			}
			catch
			{
			}
			return null;
		}
		public Slot getSlotByName(string name, string frame, TaleEntities tale)
		{
			var sl = tale.Slot.Where(s => s.Name == name && s.Frame.Name == frame);
			if (sl.Count() > 0)
				return sl.First();
			return null;
		}
		public TreeNode getSlotTreeNode(string name, TreeNode frame)
		{
			foreach (TreeNode tn in frame.Nodes)
			{
				if (tn.Text.ToLower() == name.ToLower())
				{
					return tn;
				}
			}
			return null;
		}
		public TreeNode getDomainTreeNodeByName(string name)
		{
			foreach (TreeNode tn in settings.DomainNodes)
			{
				if (tn.Text == name)
				{
					return tn;
				}
			}
			return null;
		}
		public TreeNode getFrameTreeNodeByName(string name)
		{
			foreach (TreeNode tn in settings.FrameNodes)
			{
				if (tn.Text == name)
				{
					return tn;
				}
			}
			return null;
		}
		public TreeViewNode getFrameTreeViewNodeByName(string name)
		{
			foreach (DiagramNode dn in diagram.Nodes)
			{
				if (((TreeViewNode)dn).Caption == name)
				{
					return ((TreeViewNode)dn);
				}
			}
			return null;
		}

		private void переименоватьФреймToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				tvMain.SelectedNode.Text,
				"Переименование фрейма-сущности \"" + tvMain.SelectedNode.Text + "\"",
				this,
				tvMain.SelectedNode, RenamingType.Frame);
			f.ShowDialog();
		}
		private void переToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				tvMain.SelectedNode.Text,
				"Переименование фрейма-ситуации \"" + tvMain.SelectedNode.Text + "\"",
				this,
				tvMain.SelectedNode, RenamingType.Frame);
			f.ShowDialog();
		}

		private void переименоватьСлотToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				tvMain.SelectedNode.Text,
				"Переименование слота \"" + tvMain.SelectedNode.Text + "\" во фрейме \"" + tvMain.SelectedNode.Parent.Text + "\"",
				this,
				tvMain.SelectedNode, RenamingType.Slot);
			f.ShowDialog();
		}

		private void переименоватьДоменToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				tvMain.SelectedNode.Text,
				"Переименование домена \"" + tvMain.SelectedNode.Text + "\"",
				this,
				tvMain.SelectedNode, RenamingType.Domain);
			f.ShowDialog();
		}

		private void переименоватьЗначениеДоменаToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				tvMain.SelectedNode.Text,
				"Переименование значения \"" + tvMain.SelectedNode.Text + "\" из домена \"" + tvMain.SelectedNode.Parent.Text + "\"",
				this,
				tvMain.SelectedNode, RenamingType.DomainValue);
			f.ShowDialog();
		}

		private void переименоватьФреймсущностьToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				frmEditStringParameter f = new frmEditStringParameter(
					tvMain.SelectedNode.Text,
					"Переименование фрейма-сущности \"" + tvMain.SelectedNode.Text + "\"",
					this,
					tvMain.SelectedNode, RenamingType.Frame);
				f.ShowDialog();
			}
		}

		private void переименоватьToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				frmEditStringParameter f = new frmEditStringParameter(
					tvMain.SelectedNode.Text,
					"Переименование фрейма-ситуации \"" + tvMain.SelectedNode.Text + "\"",
					this,
					tvMain.SelectedNode, RenamingType.Frame);
				f.ShowDialog();
			}
		}

		private void uncheckTsbs(ToolStripButton except)
		{
			tsbArrow.Checked = false;
			tsbHand.Checked = false;
			tsbISA.Checked = false;
			tsbNext.Checked = false;
			tsbSub.Checked = false;
			tsbZoomIn.Checked = false;
			tsbZoomOut.Checked = false;
			except.Checked = true;
		}

		private void tsbArrow_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbArrow);
			diagramView.Behavior = Behavior.Modify;
			diagramView.OverrideCursor = Cursors.Arrow;
		}

		private void tsbHand_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbHand);
			diagramView.Behavior = Behavior.Pan;
			diagramView.OverrideCursor = Cursors.SizeAll;
		}

		private void tsbISA_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbISA);
		}

		private void tsbSub_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbSub);
		}

		private void tsbNext_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbNext);
		}

		private void tsbZoomIn_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbZoomIn);
			diagramView.Behavior = Behavior.DoNothing;
			diagramView.OverrideCursor = Cursors.Cross;
		}

		private void tsbZoomOut_Click(object sender, EventArgs e)
		{
			uncheckTsbs(tsbZoomOut);
			diagramView.Behavior = Behavior.DoNothing;
			diagramView.OverrideCursor = Cursors.Cross;
		}


		private void newToolStripMenuItem_Click(object sender, EventArgs e)
		{
			//MessageBox.Show(CheckIf.ISACouldBeDeleted("Оживляющий помощник главного героя").ToString());
		}

		private void infoToolStripMenuItem_Click(object sender, EventArgs e)
		{
			// если нет запущенного winhlp32.exe
			if (Process.GetProcessesByName("winhlp32").Count() == 0)
			{
				Process proc = new Process();
				//System.IO.StreamReader f = new System.IO.StreamReader("KeyWords.txt");
				//String str = f.ReadToEnd();
				proc.StartInfo.FileName = "c:\\windows\\hh.exe";
				// сами файлы справки должны быть рядом с winhlp32.exe
				File.Copy(Directory.GetCurrentDirectory() + "\\hlp.chm", "c:\\windows\\hlp.chm", true);
				proc.StartInfo.Arguments = "hlp.chm";

				//// если есть открытые файлы
				//if (WindowCode.TabCount>0) then
				//begin
				//  // sel-выделенный текст
				//  var sel:String:=Alsing.Windows.Forms.SyntaxBoxControl(WindowCode.SelectedTab.Controls[0].Controls[0].Controls[0]).Selection.Text;
				//  if not (sel="") then 
				//  if str.Contains(sel)=true then
				//     proc.StartInfo.Arguments:=proc.StartInfo.Arguments.Insert(0,"-i "+sel+" ");
				proc.Start();
			}
		}

		private void tvMain_ClientSizeChanged(object sender, EventArgs e)
		{
			btnCollapse.Location = new Point(tvMain.ClientSize.Width - 29, btnCollapse.Location.Y);
			btnExpand.Location = new Point(tvMain.ClientSize.Width - 29 - 5 - btnCollapse.Width, btnExpand.Location.Y);
		}

		private void объяснениеToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ReasonForm rf = new ReasonForm(tale);
			rf.ShowDialog();
		}

		public DialogResult AskUser(string question)
		{
			return MessageBox.Show(question, "Внимание", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
		}

		public void InformUser(string msg)
		{
			MessageBox.Show(msg, "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		//NOT TESTED
		private void удалитьФреймToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (CheckIf.FrameCouldBeDeleted(tvMain.SelectedNode.Text))
			{
				if (AskUser(string.Format("Вы действительно хотите удалить фрейм '{0}'?", tvMain.SelectedNode.Text)) == DialogResult.OK)
				{
					RunEditForms.DeleteFrameV(GetFrameID(tvMain.SelectedNode), 2);
					deleteFrameNodes(tvMain.SelectedNode.Text);
				}
			}
			else
				InformUser(string.Format("Фрейм '{0}' нельзя удалить.", tvMain.SelectedNode.Text));
		}
		//NOT TESTED
		private void удалитьСлотToolStripMenuItem_Click(object sender, EventArgs e)
		{
			string sn = tvMain.SelectedNode.Text;
			string pn = tvMain.SelectedNode.Parent.Text;
			if (!CheckIf.SlotIsInherited(sn, pn))
			{
				if (!CheckIf.SlotIsInUse(sn, pn))
				{
					if (AskUser(string.Format("Вы действительно хотите удалить слот '{0}'?", tvMain.SelectedNode.Text)) == DialogResult.OK)
					{
						RunEditForms.DeleteSlotV(GetSlotID(tvMain.SelectedNode), GetFrameType(tvMain.SelectedNode));
						refreshFrameNodes(getFrameByName(pn, tale), pn);
					}
				}
				else
					InformUser("Слот используется в продукциях.");
			}
			else
				InformUser("Слот является наследуемым.");
		}
		//NOT TESTED
		private void удалитьДоменToolStripMenuItem_Click(object sender, EventArgs e)
		{
			TreeNode prevSN = tvMain.SelectedNode;
			string dn = tvMain.SelectedNode.Text;
			if (CheckIf.DomainCouldBeDeleted(dn))
			{
				if (AskUser(string.Format("Вы действительно хотите удалить домен '{0}'?", tvMain.SelectedNode.Text)) == DialogResult.OK)
				{
					Domains dom = getDomainByName(dn, tale);
					tale.DeleteObject(dom);
					foreach (var domval in dom.DomainsValues)
					{
						DValues dva = domval.DValues;
						tale.DeleteObject(domval);
					}
					tale.SaveChanges();
					deleteDomainNode(dn);

					RebuildDomainHierarchy();

					tvMain.SelectedNode = FindNode(tvMain.Nodes[1], dn);
				}
			}
			else
				InformUser("Домен нельзя удалить");
		}
		//NOT TESTED
		private void удалитьСитуациюToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (CheckIf.FrameCouldBeDeleted(tvMain.SelectedNode.Text))
			{
				if (AskUser(string.Format("Вы действительно хотите удалить фрейм '{0}'?", tvMain.SelectedNode.Text)) == DialogResult.OK)
				{
					RunEditForms.DeleteFrameV(GetFrameID(tvMain.SelectedNode), 1);
					deleteFrameNodes(tvMain.SelectedNode.Text);
				}
			}
			else
				InformUser(string.Format("Фрейм '{0}' нельзя удалить.", tvMain.SelectedNode.Text));
		}
		//NOT TESTED
		private void удвлитьЗначениеДоменаToolStripMenuItem_Click(object sender, EventArgs e)
		{
			TreeNode prevSN = tvMain.SelectedNode;
			string dv = tvMain.SelectedNode.Text;
			string dn = tvMain.SelectedNode.Parent.Text;
			if (tvMain.SelectedNode.Level > 2 || CheckIf.DomainValueCouldBeDeleted(dv, dn))
			{
				if (AskUser(string.Format("Вы действительно хотите вынести значение '{0}' из домена '{1}'?", dv, dn)) == DialogResult.OK)
				{
					//	string gpDom = tvMain.SelectedNode.Parent.Parent.Text;

					Domains dom = getDomainByName(dn, tale);
					DomainsValues domval = dom.DomainsValues.Where(d => d.DValues.Value == dv).First();
					//DValues dv1 = domval.DValues;
					tale.DeleteObject(domval);

					//if (gpDom == "Домены")
					//	{
					//		tale.DeleteObject(dv1);
					//	}

					tale.SaveChanges();
					RebuildDomainHierarchy();
					//RefreshDomainNodes(dom, dn);
					tvMain.SelectedNode = FindNode(tvMain.Nodes[1], dn);
				}
			}
			else
				InformUser("Значение домена нельзя удалить.");
		}

		private void btnTo100_Click(object sender, EventArgs e)
		{
			tbZoomFactor.Value = 100;
		}


		private void добавитьДоменToolStripMenuItem_Click(object sender, EventArgs e)
		{
			frmEditStringParameter f = new frmEditStringParameter(
				"",
				"Добавление домена. Укажите имя домена.",
				this,
				tvMain.SelectedNode, RenamingType.NewDomain);
			if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				Domains d = getDomainByName(f.Value, tale);
				if (d != null)
				{
					RebuildDomainHierarchy();
				}
			}
		}

		private void изменитьДоменToolStripMenuItem_Click(object sender, EventArgs e)
		{

			if (tvMain.SelectedNode.Tag.ToString() == "v")
			{
				tvMain.SelectedNode = tvMain.SelectedNode.Parent;
			}

			frmEditStringParameter f = new frmEditStringParameter(
				"",
				"Добавление значения в домен '" + tvMain.SelectedNode.Text + "'",
				this,
				tvMain.SelectedNode, RenamingType.NewDomainValue);


			if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				//TreeNode dv = new TreeNode(f.Value);
				tale = new TaleEntities();
				//RefreshDomainNodes(getDomainByName(tvMain.SelectedNode.Text, tale), tvMain.SelectedNode.Text);

				RebuildDomainHierarchy();
				//tvMain.SelectedNode.Nodes.Add()
			}
		}

		private void удалитьФреймситуациюToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (CheckIf.FrameCouldBeDeleted(tvMain.SelectedNode.Text))
			{
				if (AskUser(string.Format("Вы действительно хотите удалить фрейм '{0}'?", lastClickedNode.Caption)) == DialogResult.OK)
				{
					RunEditForms.DeleteFrameV(GetFrameID(lastClickedNode), 1);
					deleteFrameNodes(lastClickedNode.Caption);
				}
			}
			else
				InformUser(string.Format("Фрейм '{0}' нельзя удалить.", lastClickedNode.Caption));
		}

		private void удалитьФреймсущностьToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (CheckIf.FrameCouldBeDeleted(tvMain.SelectedNode.Text))
			{
				if (AskUser(string.Format("Вы действительно хотите удалить фрейм '{0}'?", lastClickedNode.Caption)) == DialogResult.OK)
				{
					RunEditForms.DeleteFrameV(GetFrameID(lastClickedNode), 2);
					deleteFrameNodes(lastClickedNode.Caption);
				}
			}
			else
				InformUser(string.Format("Фрейм '{0}' нельзя удалить.", lastClickedNode.Caption));

		}

		private void tvMain_AfterCollapse(object sender, TreeViewEventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				btnExpand.Enabled = (!tvMain.SelectedNode.IsExpanded && tvMain.SelectedNode.Nodes.Count > 0) || !HasNoCollapsedChildren(tvMain.SelectedNode);
				btnCollapse.Enabled = tvMain.SelectedNode.IsExpanded;
			}
		}

		private void tvMain_AfterExpand(object sender, TreeViewEventArgs e)
		{
			if (tvMain.SelectedNode != null)
			{
				btnExpand.Enabled = (!tvMain.SelectedNode.IsExpanded && tvMain.SelectedNode.Nodes.Count > 0) || !HasNoCollapsedChildren(tvMain.SelectedNode);
				btnCollapse.Enabled = tvMain.SelectedNode.IsExpanded;
			}
		}

		private void frmMain_Load(object sender, EventArgs e)
		{
			//string s = "Антагонист является потомком - ";
			//foreach (var item in (new TaleEntities()).Frame
			//.Where(f=> f.Name == "Оружие антагониста")
			//	)
			//{
			//	s += item.Name + ": " + CheckIf.ISADirectedCycle(item.Name,"Антагонист", new TaleEntities()).ToString() + " | ";
			//}
			//MessageBox.Show(CheckIf.GetProductionChain(57,25).Count.ToString());

			//MessageBox.Show(CheckIf.GetProductionChain(67, 67).Count.ToString());

			//DomainHierarchier.GetParent("Локатив оживлений", new TaleEntities());
		}

		private void изменитьПоддоменToolStripMenuItem_Click(object sender, EventArgs e)
		{
			TreeNode tn = tvMain.SelectedNode;
			DomainBuilder f = null;
			string dn = "";
			string gp = null;
			if (tn.Tag.ToString() == "d")
			{
				if (tn.Parent != null)
					gp = tn.Parent.Text;
				f = new DomainBuilder(this, gp, this.settings.FindLeaves(tn), tn.Text);

				dn = tn.Text;
			}
			else
				if (tn.Tag.ToString() == "v")
				{
					if (tn.Parent.Parent != null)
						gp = tn.Parent.Parent.Text;
					f = new DomainBuilder(this, gp, this.settings.FindLeaves(tn), tn.Text);
					dn = tn.Parent.Text;
				}
			if (f != null)
			{
				if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
				{

					//SynchronizeDomains(dn, f.ChosenDomainName);

					tale = new TaleEntities();

					Domains d = getDomainByName(dn, tale);

					var ds = DomainHierarchier.getDValuesStrings(d.ID);

					for (int i = d.DomainsValues.Count - 1; i >= 0; --i)
					{
						tale.DeleteObject(d.DomainsValues.ElementAt(i));
					}

					foreach (string item in f.ChosenValuesNames)
					{
						//if (!ds.Contains(item))
						{
							DomainsValues domval = new DomainsValues();
							DValues dv = tale.DValues.Where(q => q.Value == item).First();
							domval.DValues = dv;
							d.DomainsValues.Add(domval);
						}
					}
					tale.SaveChanges();


					RebuildDomainHierarchy();
				}
			}
		}

		public void SynchronizeDomains(string partDomName, string baseDomName)
		{
			tale = new TaleEntities();
			Domains partDom = getDomainByName(partDomName, tale);
			Domains baseDom = getDomainByName(baseDomName, tale);
			if (partDom != null && baseDom != null)
			{
				var diff = DomainHierarchier.getDValuesIndices(partDom.ID);
				var baseDvals = DomainHierarchier.getDValuesIndices(baseDom.ID);
				if (diff.Count > 0 && baseDvals.Count > 0)
				{
					for (int i = diff.Count - 1; i >= 0; --i)
					{
						if (baseDvals.Contains(diff[i]))
						{
							diff.RemoveAt(i);
						}
					}

					if (diff.Count > 0)
					{
						foreach (var item in diff)
						{
							DomainsValues domval = new DomainsValues();
							domval.DValues = tale.DValues.Where(dv => dv.ID == item).First();
							baseDom.DomainsValues.Add(domval);
						}
						tale.SaveChanges();

						baseDom = DomainHierarchier.GetParent(baseDom.Name, tale);

						while (baseDom != null)
						{
							foreach (var item in diff)
							{
								DomainsValues domval = new DomainsValues();
								domval.DValues = tale.DValues.Where(dv => dv.ID == item).First();
								baseDom.DomainsValues.Add(domval);
							}

							baseDom = DomainHierarchier.GetParent(baseDom.Name, tale);
							tale.SaveChanges();
						}
					}
				}
			}
		}

		private void вынестиИзОбъемлющегоToolStripMenuItem_Click(object sender, EventArgs e)
		{
			TreeNode tn = tvMain.SelectedNode;
			if (tn.Level > 1)
			{
				Domains d = getDomainByName(tn.Text, tale);
				Domains pd = getDomainByName(tn.Parent.Text, tale);
				if (d != null && pd != null)
				{
					var domvals = d.DomainsValues;

					bool allow = true;

					foreach (var toout in domvals)
					{
						if (!CheckIf.DomainValueCouldBeDeleted(toout.DValues.Value, pd.Name))
						{
							allow = false;
							break;
						}
					}
					if (allow)
					{
						foreach (var toout in domvals)
						{
							DomainsValues del = null;
							foreach (var todel in pd.DomainsValues)
							{
								if (toout.Value == todel.Value)
								{
									del = todel;
									break;
								}
							}
							if (del != null)
								tale.DeleteObject(del);
						}
						tale.SaveChanges();
						RebuildDomainHierarchy();
					}
					else
						InformUser("Домен нельзя вынести из объемлющего. Значения используются в продукциях.");
				}
			}
		}

		private void cmsTv_Opening(object sender, CancelEventArgs e)
		{

		}

		private void сделатьДоменПоддоменомToolStripMenuItem_Click(object sender, EventArgs e)
		{
			MakeSubDomain f = new MakeSubDomain(tvMain.SelectedNode.Text);

			if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				SynchronizeDomains(tvMain.SelectedNode.Text, f.ChosenDomainName);
				RebuildDomainHierarchy();
			}
		}

		private void удалитьЗначениеИзДоменаToolStripMenuItem_Click(object sender, EventArgs e)
		{
			TreeNode prevSN = tvMain.SelectedNode;
			string dv = tvMain.SelectedNode.Text;
			string dn = tvMain.SelectedNode.Parent.Text;
			TreeNode tmp = tvMain.SelectedNode.Parent;

			while (tmp!= null && CheckIf.DomainValueCouldBeDeleted(dv, tmp.Text))
			{
				tmp = tmp.Parent;
			}

			if (tmp == null)
			{
				if (AskUser(string.Format("Вы действительно хотите удалить значение '{0}' из всех содержащих его доменов?", dv)) == DialogResult.OK)
				{
					tmp = tvMain.SelectedNode.Parent;
					DValues dv1 = null;
					while (tmp.Level >= 1)
					{
						Domains dom = getDomainByName(tmp.Text, tale);
						DomainsValues domval = dom.DomainsValues.Where(d => d.DValues.Value == dv).First();
						dv1 = domval.DValues;
						tale.DeleteObject(domval);
						tmp = tmp.Parent;
					}

					tale.SaveChanges();
					RebuildDomainHierarchy();
					tvMain.SelectedNode = FindNode(tvMain.Nodes[1], dn);
				}
			}
			else
				InformUser("Значение домена нельзя удалить.");
		}

		private void arrowToolStripMenuItem_Click(object sender, EventArgs e)
		{
			tsbArrow.PerformClick();
		}

		private void moveToolStripMenuItem_Click(object sender, EventArgs e)
		{
			tsbHand.PerformClick();
		}

		private void zoominToolStripMenuItem_Click(object sender, EventArgs e)
		{
			tsbZoomIn.PerformClick();
		}

		private void zoomoutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			tsbZoomOut.PerformClick();
		}
	}
}

